//
//  KpiQuartzView.m
//  AppFinance
//
//  Created by wei on 12-7-15.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "AFKpiQuartzView.h"

#import "AFUtils.h"

#import "AFSetting.h"

#import "AFMACD.h"
#import "AFVOL.h"
#import "AFRSI.h"
#import "AFBOLL.h"
#import "AFKDJ.h"
#import "AFKpiOBV.h"
#import "AFCCI.h"
#import "AFPSY.h"

@implementation AFKpiQuartzView

- (void) distory {
    isDistroy = YES;
    
    [self setNeedsDisplay];
}

- (void) initKLineArray:(NSMutableArray*)array kpiType:(int)type isLast:(BOOL)isLast{
    
    // 是否刷新最后一条 K Line 数据
    if (isLast) {
        if ((S_DRAW_INDEX + [AFSetting AF_DRAW_COUNT]) >= ALL_COUNT) {
            NSLog(@" kpi udate last k line data ");
        } else {
            NSLog(@" kpi no need udate last k line data ");
            return;
        }
    }
    
    s_x = 0;  // 开始 x 坐标点
    s_y = 0;  // 开始 y 坐标点
    
    kLineArray = array;
    kpiType = type;
    
    ALL_COUNT = (int)[array count];
    
    S_DRAW_INDEX = 0;
    if (ALL_COUNT > [AFSetting AF_DRAW_COUNT]) {
        S_DRAW_INDEX = ALL_COUNT - [AFSetting AF_DRAW_COUNT];
    }
    
    F_DRAW_INDEX = S_DRAW_INDEX;
    
    [self initData];
    
    [self drawArrayRefresh];
}

- (void) initData{
    // MACD
    macdData = nil;
    difData = nil;
    dmData = nil;
    
    draw_macdData = nil;
    draw_difData = nil;
    draw_dmData = nil;
    
    macd_min = 0;
    macd_max = 0;
    
    macd_lastDif = 0;
    macd_lastMacd = 0;
    macd_lastDm = 0;
    
    // VOL
    volBarData = nil;
    volLineDataM5 = nil;
    volLineDataM10 = nil;
    
    draw_volBarData = nil;
    draw_volLineDataM5 = nil;
    draw_volLineDataM10 = nil;
    
    vol_max = 0;
    
    vol_lastVol = 0;
    vol_lastM5 = 0;
    vol_lastM10 = 0;
    
    // RSI
    rsiDataM6 = nil;
    rsiDataM12 = nil;
    
    draw_rsiDataM6 = nil;
    draw_rsiDataM12 = nil;
    
    rsi_min = 0;
    rsi_max = 0;
    
    rsi_lastM6 = 0;
    rsi_lastM12 = 0;
    
    // BOLL
    bool_averageArray = nil;
    bool_upArray = nil;
    bool_downArray = nil;
    
    draw_bool_averageArray = nil;
    draw_bool_upArray = nil;
    draw_bool_downArray = nil;
    
    bool_min = 0;
    bool_max = 0;
    
    bool_last_mid = 0;
    bool_lastup = 0;
    bool_last_down = 0;
    
    // KDJ
    kdj_k_dataArray = nil;
    kdj_d_dataArray = nil;
    kdj_j_dataArray = nil;
    
    draw_kdj_k_dataArray = nil;
    draw_kdj_d_dataArray = nil;
    draw_kdj_j_dataArray = nil;
    
    kdj_min = 0;
    kdj_max = 0;
    
    kdj_last_k = 0;
    kdj_last_d = 0;
    kdj_last_j = 0;
    
    // OBV
    obv_array = nil;
    
    draw_obv_array = nil;
    
    obv_min = 0;
    obv_max = 0;
    
    obv_last = 0;
    
    // CCI
    cci_array = nil;
    
    draw_cci_array = nil;
    
    cci_min = 0;
    cci_max = 0;
    
    cci_last = 0;
    
    // PSY
    psy_array = nil;
    
    draw_psy_array = nil;
    
    psy_min = 0;
    psy_max = 0;
    
    psy_last = 0;
}

- (void) changeKpiType:(int)type{
    kpiType = type;
    [self drawArrayRefresh];
}

// 把 将要绘制的 原始数据 转换成 本地 坐标数据
- (void) drawArrayRefresh{
    NSLog(@"ALL_COUNT = %i, S_DRAW_INDEX = %i", ALL_COUNT, S_DRAW_INDEX);

    [self setNeedsDisplay];
}

// 根据手指移动 的 距离 刷新 要绘制的 K Line
// @orientation 1 left 2 right
- (void) touchMoveRefreshDrawArrayWithOrientation:(int) orientation{
    //NSLog(@" start_touch_x = %i, move_touch_x = %i", start_touch_x, move_touch_x);

    if (orientation == 1) {
        if (S_DRAW_INDEX > 0) {
            S_DRAW_INDEX --;
            
            [self drawArrayRefresh];
        }
    } else {
        if (S_DRAW_INDEX < F_DRAW_INDEX) {
            S_DRAW_INDEX ++;
            
            [self drawArrayRefresh];
        }
    }
    
    [self setNeedsDisplay];
}

#define mark - draw context
-(void)drawInContext:(CGContextRef)context rect:(CGRect)rect{
    
    NSLog(@"------- StockDayQuartzView drawInContext ----");
    
    if (isDistroy) {
        isDistroy = NO;
        [self draw4distory:context];
        return;
    }
    
    // 绘制背景框
    [self drawBackGround:context];
    
    // 开始绘制烛台图
    //[self drawZhuTai:context];
    
    // 开始绘制MA
    //[self drawMA:context];
    
    // 0: MACD平滑异同平均线
    // 1: VOL成交量
    // 2: RSI强弱指标
    // 3: BOLL布林线
    // 4: KDJ随机指标
    // 5: OBV能量潮
    // 6: CCI顺势
    // 7: PSY心里线
    if (kpiType == 0) {
        [self drawMACD:context];
    } else if (kpiType == 1) {
        [self drawVOL:context];
    } else if (kpiType == 2) {
        [self drawRSI:context];
    }  else if (kpiType == 3) {
        [self drawBOLL:context];
    } else if (kpiType == 4) {
        [self drawKDJ:context];
    } else if (kpiType == 5) {
        [self drawOBV:context];
    } else if (kpiType == 6) {
        [self drawCCI:context];
    } else if (kpiType == 7) {
        [self drawPSY:context];
    }
    
    [self NotifKpiDateUpdate];
}

- (void) draw4distory:(CGContextRef)context{
    // 绘制前，先清楚所有绘图区域
    CGContextClearRect(context, CGRectMake(0, 0, [AFSetting QUARTZ_KPI_W], [AFSetting QUARTZ_KPI_H]));
    // 绘制背景框
    [self drawBackGround:context];
}

// 绘制背景框
-(void) drawBackGround :(CGContextRef)context{
    
    // 绘制前，先清楚所有绘图区域
    CGContextClearRect(context, CGRectMake(0, 0, [AFSetting QUARTZ_KPI_W], [AFSetting QUARTZ_KPI_H]));
    
    // 设置线宽
    CGContextSetLineWidth(context, 1.0f);
    //CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
    CGContextSetStrokeColorWithColor(context, AF_K_QUARTZ_DRAW_BORDER_CGCOLOR);
    
    // 绘制边框
    CGContextAddRect(context, CGRectMake(0, 0, [AFSetting QUARTZ_KPI_W], [AFSetting QUARTZ_KPI_H]));
    CGContextStrokePath(context);
    
    // 分时背景虚线
    // 虚线设置
    CGContextSetStrokeColorWithColor(context, AF_K_QUARTZ_DRAW_BORDER_CGCOLOR_daush);
    CGContextSetLineWidth(context, 0.2);
    
   	CGFloat dashPhase = 2.0;
	CGFloat dashPattern[2] = {4.0, 4.0};
	size_t dashCount = 2;
    CGContextSetLineDash(context, dashPhase, dashPattern, dashCount);
    
    // 竖线
    CGContextMoveToPoint(context, [AFSetting QUARTZ_KPI_W]/4, 1);
    CGContextAddLineToPoint(context, [AFSetting QUARTZ_KPI_W]/4, [AFSetting QUARTZ_KPI_H] - 2);
    
    CGContextMoveToPoint(context, [AFSetting QUARTZ_KPI_W]/2, 1);
    CGContextAddLineToPoint(context, [AFSetting QUARTZ_KPI_W]/2, [AFSetting QUARTZ_KPI_H] - 2);
    
    CGContextMoveToPoint(context, [AFSetting QUARTZ_KPI_W]/4*3, 1);
    CGContextAddLineToPoint(context, [AFSetting QUARTZ_KPI_W]/4*3, [AFSetting QUARTZ_KPI_H] - 2);
    
    // 横线
    CGContextMoveToPoint(context, 1, [AFSetting QUARTZ_KPI_H]/2);
    CGContextAddLineToPoint(context, [AFSetting QUARTZ_KPI_W], [AFSetting QUARTZ_KPI_H]/2);
    
    CGContextStrokePath(context);
    CGContextSetLineDash(context, 0, 0, 0); //取消虚线
}

#pragma mark ========== MACD ========== 
//底部图范围:  左上角坐标(0,0) -- 右下角(320,70)
- (void) drawMACD:(CGContextRef)context{
    if ([kLineArray count] == 0) {
        return;
    }

    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];

    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }

    // 初始化 KPI 数据
    if (macdData == nil) {
        // KPI MACD
        [[AFMACD app] initKlineArray:kLineArray];
        [[AFMACD app] macdData:DRAW_COUNT];
        
        macdData = [[AFMACD app] kpiMacdListArray];
        difData = [[AFMACD app] kpiDifListArray];
        dmData = [[AFMACD app] kpiDmListArray];
        
        macd_min = [AFMACD kpiMinMacd];
        macd_max = [AFMACD kpiMaxMacd];
    }

    // 获取 要绘制的 数据
    draw_macdData = [macdData subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_difData = [difData subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_dmData = [dmData subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    
    //*
    macd_min = 100000;
    macd_max = 0;
    int macd_count = (int)[draw_macdData count];
    float f_min_max = 0;
    for (int i = 0; i < macd_count; i++) {
        f_min_max = [[draw_macdData objectAtIndex:i] floatValue];
        
        if (macd_max < f_min_max) {
            macd_max = f_min_max;
        }
        if (macd_min > f_min_max) {
            macd_min = f_min_max;
        }
        
        f_min_max = [[draw_difData objectAtIndex:i] floatValue];
        
        if (macd_max < f_min_max) {
            macd_max = f_min_max;
        }
        if (macd_min > f_min_max) {
            macd_min = f_min_max;
        }
        
        f_min_max = [[draw_dmData objectAtIndex:i] floatValue];
        
        if (macd_max < f_min_max) {
            macd_max = f_min_max;
        }
        if (macd_min > f_min_max) {
            macd_min = f_min_max;
        }
    }
    
    //*/

    // 要绘制到 的 记录 的 index
    //int T_DRAW_INDEX = S_DRAW_INDEX + DRAW_COUNT;
    //NSLog(@" ALL_COUNT = %i, S_DRAW_INDEX = %i, T_DRAW_INDEX = %i", ALL_COUNT, S_DRAW_INDEX, T_DRAW_INDEX);
    //NSLog(@" kminMacd = %f, kmaxMacd = %f",macd_min, macd_max);
    
    draw_DataA = nil;
    draw_DataB = nil;
    draw_DataC = nil;
    draw_DataA = difData;
    draw_DataB = macdData;
    draw_DataC = dmData;
    
    // 计算 x 轴上 每段 长度
    // 要绘制的条数
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    // 计算中间横线坐标
    float min_h = [AFSetting QUARTZ_KPI_H]/((fabsf(macd_max) +  fabsf(macd_min)));
    float splite_y = s_y + min_h*fabsf(macd_max);
    
    // 绘制MACD中间分割线
    CGContextSetLineWidth(context, 2.0);
    
    // dm MACD 柱状图
    float dm = 0;
    float dm_sx = 0;
    float dm_sy = splite_y;
    float dm_ey = 0;
    
    // DM
    int dm_count = (int)[draw_dmData count];
    for(int i = 0; i < dm_count; i++){
        dm = [[draw_dmData objectAtIndex:i] floatValue];
        
        dm_sx = s_x + i*min_w + min_w/2;
        if(dm > 0){
            dm_ey = splite_y - dm*min_h;
              CGContextSetRGBStrokeColor(context,0.89, 0.133, 0.133, 1.0);
            CGContextSetFillColorWithColor(context, AF_K_QUARTZ_KLINE_UP_CGCOLOR);
        } else{
            dm_ey = splite_y + fabsf(dm)*min_h; 
            CGContextSetRGBStrokeColor(context, 0.067, 0.62, 0.067, 1.0);
        }

        if(isnan(dm_sy) || isnan(dm_ey)){
            return ;
        }
        CGContextMoveToPoint(context, dm_sx, dm_sy);
        CGContextAddLineToPoint(context, dm_sx, dm_ey);
        CGContextStrokePath(context);
        
        
        macd_lastDm = dm;
    }

    // DIF
    if (difData != nil) {
        CGContextSetLineWidth(context, 1.0);
//        CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
        //  橘黄色
        CGContextSetRGBStrokeColor(context, 253.0f/255.0f, 160.0f/255.0f, 28.0f/255.0f, 1.0);
        
        float dif = 0;
        float x = 0;
        float y = 0;
        
        int dif_count = (int)[draw_difData count];
        for(int i = 0; i < dif_count; i++){
            dif = [[draw_difData objectAtIndex:i] floatValue];
            
            x = s_x + i * min_w + min_w/2;
            if(dif> 0){
                y = splite_y - dif*min_h;
            }else{
                y = splite_y + fabsf(dif)*min_h;
            }

            if(i == 0){
                CGContextMoveToPoint(context, x, y); // 移动到起点坐标
            } else {
                // 增加新的坐标点
                CGContextAddLineToPoint(context, x, y);
            }
            
            macd_lastDif = dif;
        }
        CGContextStrokePath(context);
    }
    
    // MACD
    if (macdData != nil) {
        CGContextSetLineWidth(context, 1.0);
//        CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0);
         CGContextSetRGBStrokeColor(context, 101.0f/255.0f, 180.0f/255.0f, 255.0f/255.0f, 1.0); // 蓝色
        
        
        float macd = 0;
        float x = 0;
        float y = 0;
        
        int macd_count = (int)[draw_macdData count];
        for(int i = 0; i < macd_count; i++){
            macd = [[draw_macdData objectAtIndex:i] floatValue];
            
            x = s_x + i*min_w + min_w/2;
            if(macd > 0){
                y = splite_y - macd*min_h;
            }else{
                y = splite_y + fabsf(macd)*min_h;
            }
            
            if(i == 0){
                CGContextMoveToPoint(context, x, y); // 移动到起点坐标
            } else {
                // 增加新的坐标点
                CGContextAddLineToPoint(context, x, y);
            }
            
            macd_lastMacd = macd;
        }

        CGContextStrokePath(context);
    }
}

- (float) macdMin{
    return macd_min;
}
- (float) macdMax{
    return macd_max;
}
- (float) macdLastDif{
    return macd_lastDif;
}
- (float) macdLastMacd{
    return macd_lastMacd;
}
- (float) macdLastDm{
    return macd_lastDm;
}

#pragma mark ========== VOL ==========
- (void) drawVOL:(CGContextRef)context{
    
    //NSLog(@" start drawVOL");
    // 获取当前的 k line 数据
    if ([kLineArray count] == 0) {
        return;
    }
    
    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];
    
    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }

    if (volBarData == nil) {
        // KPI VOL
        [[AFVOL app] initKlineArray:kLineArray];
        
        vol_max = [[AFVOL app] maxVolume:DRAW_COUNT];
        if(vol_max == 0.0f){
            return;
        }
        
        volBarData = [[AFVOL app] volBarData];
        volLineDataM5 = [[AFVOL app] volLineData:5];
        volLineDataM10 = [[AFVOL app] volLineData:10];
    }
    
    NSLog(@" volBarData count = %i", (int)[volBarData count]);
    NSLog(@" volLineDataM5 count = %i", (int)[volLineDataM5 count]);
    NSLog(@" volLineDataM10 count = %i", (int)[volLineDataM10 count]);
    
    NSLog(@" S_DRAW_INDEX = %i, DRAW_COUNT = %i", S_DRAW_INDEX, DRAW_COUNT);
    
    // 获取 要绘制的 数据
    draw_volBarData = [volBarData subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_volLineDataM5 = [volLineDataM5 subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_volLineDataM10 = [volLineDataM10 subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    
    float volume_h = [AFSetting QUARTZ_KPI_H]/vol_max; // 实际高度／间隔高度 ＝ y轴分段高度
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    NSDictionary *dict;
    NSString *stauts;
    float volume;
    
    float x1,y1;
    CGContextSetLineWidth(context, 0.8);
    
    draw_DataA = nil;
    draw_DataB = nil;
    draw_DataC = nil;
    draw_DataA = volBarData;
    draw_DataB = volLineDataM5;
    draw_DataC = volLineDataM10;

    // 绘制vol数据
    int r_h = 0;
    int volBar_count = (int)[draw_volBarData count];
    for (int i = 0; i< volBar_count; i++) {
        dict = [draw_volBarData objectAtIndex:i];
        stauts = [dict objectForKey:AF_K_MARKET_STATUS];
        volume = [[dict objectForKey:AF_K_MARKET_VOLUME] floatValue];
        
        x1 = s_x + i*min_w + 1; //min_w/2;
        y1 = [AFSetting QUARTZ_KPI_H] - volume*volume_h; // y 最大坐标 － 换算后的高度 ＝ y轴新的坐标
        r_h = volume*volume_h;;
        

        if ([stauts isEqualToString:@"up"]) {
            CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
            CGContextAddRect(context, CGRectMake(x1, y1, min_w-2, r_h));
             CGContextStrokePath(context);
        } else {
            CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1.0);
            CGContextAddRect(context, CGRectMake(x1, y1, min_w-2, r_h));
            CGContextFillPath(context);
        }
        
        vol_lastVol = volume;
    }
    
    // 绘制vol m5 数据
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0);
     CGContextSetRGBStrokeColor(context, 36.0f/255.0f, 172.0f/255.0f, 238.0f/255.0f, 1.0); // 蓝色
    
    float volM5 = 0;
    int volM5_count = (int)[draw_volLineDataM5 count];
    for (int i = 0; i< volM5_count; i++) {
        volM5 = [[draw_volLineDataM5 objectAtIndex:i] floatValue];

        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - volM5*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
        vol_lastM5 = volM5;
    }
    CGContextStrokePath(context);
    
    // 绘制vol m10 数据
    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 1.0, 1.0);

    float volM10 = 0;
    int volM10_count = (int)[draw_volLineDataM10 count];
    for (int i = 0; i< volM10_count; i++) {
        volM10 = [[draw_volLineDataM10 objectAtIndex:i] floatValue];

        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - volM10*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
        vol_lastM10 = volM10;
    }
    CGContextStrokePath(context);
}

- (float) volMax{
    return vol_max;
}
- (float) volLastVol{
    return vol_lastVol;
}
- (float) volLastM5{
    return vol_lastM5;
}
- (float) volLastM10{
    return vol_lastM10;
}

#pragma mark ========== RSI ==========
- (void) drawRSI:(CGContextRef)context{
    
    //NSLog(@" start drawVOL");
    // 获取当前的 k line 数据
    if ([kLineArray count] == 0) {
        return;
    }
    
    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];
    
    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }

    if (rsiDataM6 == nil) {
        // KPI RSI
        [[AFRSI app] initKlineArray:kLineArray];
        
        // RSI DATA M6
        rsiDataM6 = [[AFRSI app] rsiData:6 drawCount:DRAW_COUNT];
        rsiDataM12 = [[AFRSI app] rsiData:12 drawCount:DRAW_COUNT];
        
        //rsi_min = [RSI kpiMinRsi];
        //rsi_max = [RSI kpiMaxRsi];
    }

    rsi_min = 100000000;
    rsi_max = 0;
    
    // 获取 要绘制的 数据
    draw_rsiDataM6 = [rsiDataM6 subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_rsiDataM12 = [rsiDataM12 subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    
    float temp_m6;
    float temp_m12;
    for (int i = 0 ; i < [draw_rsiDataM6 count]; i++) {
        temp_m6 = [[draw_rsiDataM6 objectAtIndex:i] floatValue];
        temp_m12 = [[draw_rsiDataM12 objectAtIndex:i] floatValue];
        
        // 获取 min max rsi
        if(rsi_min > temp_m6){
            rsi_min = temp_m6;
        }
        if(rsi_max < temp_m6){
            rsi_max = temp_m6;
        }
        
        if(rsi_min > temp_m12){
            rsi_min = temp_m12;
        }
        if(rsi_max < temp_m12){
            rsi_max = temp_m12;
        }
    }

    float x1,y1;
    
    // 绘制vol m6 数据
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    //  橘黄色
    CGContextSetRGBStrokeColor(context, 253.0f/255.0f, 160.0f/255.0f, 28.0f/255.0f, 1.0);
    
    NSLog(@" rsi_min = %f", rsi_min);
    NSLog(@" rsi_max = %f", rsi_max);
    NSLog(@" [RSI kpiMaxRsi] = %f",[AFRSI kpiMaxRsi]);
    
    float volume_h = [AFSetting QUARTZ_KPI_H]/ (rsi_max - rsi_min); // 实际高度／间隔高度 ＝ y轴分段高度
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    float rsi = 0;
    int m6_count = (int)[draw_rsiDataM6 count];
    for (int i = 0; i< m6_count; i++) {
        rsi = [[draw_rsiDataM6 objectAtIndex:i] floatValue];
        rsi_lastM6 = rsi;
        
        rsi = rsi - rsi_min;
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - rsi*volume_h;
        if(isnan(y1)){
            return;
        }
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
    }
    CGContextStrokePath(context);
    
    // 绘制vol m12 数据
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0);
     CGContextSetRGBStrokeColor(context, 101.0f/255.0f, 180.0f/255.0f, 255.0f/255.0f, 1.0); // 蓝色
    int m12_count = (int)[draw_rsiDataM12 count];
    for (int i = 0; i< m12_count; i++) {
        rsi = [[draw_rsiDataM12 objectAtIndex:i] floatValue];
        
        rsi_lastM12 = rsi;
        
        rsi = rsi - rsi_min;
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - rsi*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
    }
    CGContextStrokePath(context);
}

- (float) rsiMin{
    return rsi_min;
}
- (float) rsiMax{
    return rsi_max;
}
- (float) rsiLastM6{
    return rsi_lastM6;
}
- (float) rsiLastM12{
    return rsi_lastM12;
}

#pragma mark ========== BOLL ========== 
- (void) drawBOLL:(CGContextRef)context{
    //NSLog(@" start drawVOL");
    // 获取当前的 k line 数据
    if ([kLineArray count] == 0) {
        return;
    }
    
    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];
    
    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }
    
    // BOLL
    if (bool_averageArray == nil) {
        [[AFBOLL app] initKlineArray:kLineArray];

        [[AFBOLL app] bollData:10 drawCount:DRAW_COUNT];
        
        bool_averageArray = [[AFBOLL app] kaverageArray];
        bool_upArray = [[AFBOLL app] kupArray];
        bool_downArray = [[AFBOLL app] kdownArray];
        
        bool_max = [AFBOLL kpiMaxBoll];
        bool_min = [AFBOLL kpiMinBoll];
        
        NSLog(@" bool_averageArray count = %i", (int)[bool_averageArray count]);
        NSLog(@" bool_upArray count = %i", (int)[bool_upArray count]);
        NSLog(@" bool_downArray count = %i", (int)[bool_downArray count]);
    }

    // 获取 要绘制的 数据
    draw_bool_averageArray = [bool_averageArray subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_bool_upArray = [bool_upArray subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_bool_downArray = [bool_downArray subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    
    //*
    bool_min = 10000;
    bool_max = 0;
    int bool_count = (int)[draw_bool_averageArray count];
    float f_min_max = 0;
    for (int i = 0; i < bool_count; i++) {
//        f_min_max = [[draw_bool_averageArray objectAtIndex:i] floatValue];
//        
//        if (bool_max < f_min_max) {
//            bool_max = f_min_max;
//        }
//        if (bool_min > f_min_max) {
//            bool_min = f_min_max;
//        }
//        
        f_min_max = [[draw_bool_upArray objectAtIndex:i] floatValue];
        
        if (bool_max < f_min_max) {
            bool_max = f_min_max;
        }
        if (bool_min > f_min_max) {
            bool_min = f_min_max;
        }
        
        f_min_max = [[draw_bool_downArray objectAtIndex:i] floatValue];
        
        if (bool_max < f_min_max) {
            bool_max = f_min_max;
        }
        if (bool_min > f_min_max) {
            bool_min = f_min_max;
        }
    }
    //*/

    float volume_h = [AFSetting QUARTZ_KPI_H]/ (bool_max - bool_min);  // 实际高度／间隔高度 ＝ y轴分段高度
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    float x1,y1;
    
    // 绘制BOLL average 数据
    CGContextSetLineWidth(context, 1.0);
    // 白色
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    //  橘黄色
    CGContextSetRGBStrokeColor(context, 253.0f/255.0f, 160.0f/255.0f, 28.0f/255.0f, 1.0);
    
    float average = 0;
    int average_count = (int)[draw_bool_averageArray count];
    for (int i = 0; i< average_count; i++) {
        average = [[draw_bool_averageArray objectAtIndex:i] floatValue];

        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - (average - bool_min)*volume_h;
        if(isnan(y1)){
            return;
        }
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
        bool_last_mid = average;
    }
    CGContextStrokePath(context);
    
    // 绘制 BOLL UP 数据
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0); // 黄色
    CGContextSetRGBStrokeColor(context, 101.0f/255.0f, 180.0f/255.0f, 255.0f/255.0f, 1.0); // 蓝色
    float up = 0;
    int up_count = (int)[draw_bool_upArray count];
    for (int i = 0; i< up_count; i++) {
        up = [[draw_bool_upArray objectAtIndex:i] floatValue];
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - (up - bool_min)*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
        bool_lastup = up;
    }
    CGContextStrokePath(context);

    // 绘制 BOLL DOWN 数据
    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 1.0, 1.0); // 紫色
    float down = 0;
    int down_count = (int)[draw_bool_downArray count];
    for (int i = 0; i< down_count; i++) {
        down = [[draw_bool_downArray objectAtIndex:i] floatValue];

        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - (down - bool_min)*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
        bool_last_down = down;
    }
    CGContextStrokePath(context);
}
- (float) boolMin{
    return bool_min;
}
- (float) boolMax{
    return bool_max;
}
- (float) boolLastMid{
    return bool_last_mid;
}
- (float) boolLastUp{
    return bool_lastup;
}
- (float) boolLastDown{
    return bool_last_down;
}

#pragma mark ========== KDJ ========== 
- (void) drawKDJ:(CGContextRef)context{
    
    //NSLog(@" start drawVOL");
    // 获取当前的 k line 数据
    if ([kLineArray count] == 0) {
        return;
    }
    
    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];
    
    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }
    
    if (kdj_k_dataArray == nil) {
        // KPI KDJ
        [[AFKDJ app] initKlineArray:kLineArray];
        
        // RSI DATA M6
        [[AFKDJ app] kdjData];
        kdj_k_dataArray = [[AFKDJ app] kArrayData];
        kdj_d_dataArray = [[AFKDJ app] dArrayData];
        kdj_j_dataArray = [[AFKDJ app] jArrayData];
        
        kdj_min = [AFKDJ kpiMinKdj];
        kdj_max = [AFKDJ kpiMaxKdj];
    }

    // 获取 要绘制的 数据
    draw_kdj_k_dataArray = [kdj_k_dataArray subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_kdj_d_dataArray = [kdj_d_dataArray subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    draw_kdj_j_dataArray = [kdj_j_dataArray subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    
    //*
    kdj_min = 10000;
    kdj_max = 0;
    int kdj_count = (int)[draw_kdj_k_dataArray count];
    float f_min_max = 0;
    for (int i = 0; i < kdj_count; i++) {
        f_min_max = [[draw_kdj_k_dataArray objectAtIndex:i] floatValue];
        
        if (kdj_max < f_min_max) {
            kdj_max = f_min_max;
        }
        if (kdj_min > f_min_max) {
            kdj_min = f_min_max;
        }
        
        f_min_max = [[draw_kdj_d_dataArray objectAtIndex:i] floatValue];
        
        if (kdj_max < f_min_max) {
            kdj_max = f_min_max;
        }
        if (kdj_min > f_min_max) {
            kdj_min = f_min_max;
        }
        
        f_min_max = [[draw_kdj_j_dataArray objectAtIndex:i] floatValue];
        
        if (kdj_max < f_min_max) {
            kdj_max = f_min_max;
        }
        if (kdj_min > f_min_max) {
            kdj_min = f_min_max;
        }
    }
    //*/

    float x1,y1;
    
    // 绘制 K
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    // 橘黄色
    CGContextSetRGBStrokeColor(context, 253.0f/255.0f, 160.0f/255.0f, 28.0f/255.0f, 1.0);
    
    NSLog(@" [RSI kpiMaxRsi] = %f",kdj_max);
    
    float volume_h = [AFSetting QUARTZ_KPI_H]/ (kdj_max - kdj_min); // 实际高度／间隔高度 ＝ y轴分段高度
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    float kdj = 0;
    int k_count = (int)[draw_kdj_k_dataArray count];
    for (int i = 0; i< k_count; i++) {
        kdj = [[draw_kdj_k_dataArray objectAtIndex:i] floatValue];
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - kdj*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
        kdj_last_k = kdj;
    }
    CGContextStrokePath(context);
    
    // 绘制 D
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0);
     CGContextSetRGBStrokeColor(context, 101.0f/255.0f, 180.0f/255.0f, 255.0f/255.0f, 1.0); // 蓝色
    
    int d_count = (int)[draw_kdj_d_dataArray count];
    for (int i = 0; i< d_count; i++) {
        kdj = [[draw_kdj_d_dataArray objectAtIndex:i] floatValue];
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - kdj*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
         kdj_last_d = kdj;
    }
    CGContextStrokePath(context);
    
    
    // 绘制 J
    CGContextSetLineWidth(context, 1.0);
    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 1.0, 1.0);
    
    int j_count = (int)[draw_kdj_j_dataArray count];
    for (int i = 0; i< j_count; i++) {
        kdj = [[draw_kdj_j_dataArray objectAtIndex:i] floatValue];
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - kdj*volume_h;
        
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
        
         kdj_last_j = kdj;
    }
    CGContextStrokePath(context);
}

- (float) kdjMin{
    return kdj_min;
}
- (float) kdjMax{
    return kdj_max;
}
- (float) kdjLastK{
    return kdj_last_k;
}
- (float) kdjLastD{
    return kdj_last_d;
}
- (float) kdjLastJ{
    return kdj_last_j;
}

#pragma mark ========== OBV ========== 
- (void) drawOBV:(CGContextRef)context{
    
    //NSLog(@" start drawVOL");
    // 获取当前的 k line 数据
    if ([kLineArray count] == 0) {
        return;
    }
    
    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];
    
    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }
    
    if (obv_array == nil) {
        [[AFKpiOBV app] initKlineArray:kLineArray];
        
        [[AFKpiOBV app] obvData:12];
        
        obv_array = [[AFKpiOBV app] kObvArray];
        
        obv_min = [AFKpiOBV kpiMinObv];
        obv_max = [AFKpiOBV kpiMaxObv];
    }
    
    if ([obv_array count] < (S_DRAW_INDEX + DRAW_COUNT)) {
        return;
    }
    
    draw_obv_array = [obv_array subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    
    //*
    obv_min = 10000;
    obv_max = 0;
    int obv_count = (int)[draw_obv_array count];
    float f_min_max = 0;
    for (int i = 0; i < obv_count; i++) {
        f_min_max = [[draw_obv_array objectAtIndex:i] floatValue];
        
        if (obv_max < f_min_max) {
            obv_max = f_min_max;
        }
        if (obv_min > f_min_max) {
            obv_min = f_min_max;
        }
    }
    //*/

    
    float x1,y1;
    
    // 绘制 K
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    //  橘黄色
    CGContextSetRGBStrokeColor(context, 253.0f/255.0f, 160.0f/255.0f, 28.0f/255.0f, 1.0);
    
    float volume_h = [AFSetting QUARTZ_KPI_H]/(obv_max - obv_min); // 实际高度／间隔高度 ＝ y轴分段高度
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    if (isinf(volume_h)) {
        return;
    }
    
    float obv = 0;
    int _count = (int)[draw_obv_array count];
    for (int i = 0; i< _count; i++) {
        obv = [[draw_obv_array objectAtIndex:i] floatValue];
        
        obv_last = obv;
    
        obv = obv - obv_min;
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - obv*volume_h;

        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
    }
    
    CGContextStrokePath(context);
}

- (float) obvMin{
    return obv_min;
}
- (float) obvMax{
    return obv_max;
}
- (float) obvLast{
    return obv_last;
}

#pragma mark ========== CCI ========== 
- (void) drawCCI:(CGContextRef)context{
    //NSLog(@" start drawVOL");
    // 获取当前的 k line 数据
    if ([kLineArray count] == 0) {
        return;
    }
    
    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];
    
    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }
    
    if (cci_array == nil) {
        // CCI
        [[AFCCI app] initKlineArray:kLineArray];
        
        // RSI DATA M6
        [[AFCCI app] cciData];
        
        cci_array = [[AFCCI app] kCCIArray];
        
        cci_min = [AFCCI kpiMinCCI];
        cci_max= [AFCCI kpiMaxCCI];
    }

    draw_cci_array = [cci_array subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];

    //*
    cci_min = 10000;
    cci_max = 0;
    int cci_count = (int)[draw_cci_array count];
    float f_min_max = 0;
    for (int i = 0; i < cci_count; i++) {
        f_min_max = [[draw_cci_array objectAtIndex:i] floatValue];
        
        if (cci_max < f_min_max) {
            cci_max = f_min_max;
        }
        if (cci_min > f_min_max) {
            cci_min = f_min_max;
        }
    }
    //*/
    
    float x1,y1;
    
    // 绘制 K
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0);
     CGContextSetRGBStrokeColor(context, 101.0f/255.0f, 180.0f/255.0f, 255.0f/255.0f, 1.0); // 蓝色
    
    float volume_h = [AFSetting QUARTZ_KPI_H]/(cci_max - cci_min); // 实际高度／间隔高度 ＝ y轴分段高度
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    float cci = 0;
    int _count = (int)[draw_cci_array count];
    for (int i = 0; i< _count; i++) {
        cci = [[draw_cci_array objectAtIndex:i] floatValue];
        
        cci_last = cci;
        
        cci = cci - cci_min;
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - cci*volume_h;

        if(isnan(y1)){
            return;
        }
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
    }
    
    CGContextStrokePath(context);
}

- (float) cciMin{
    return cci_min;
}
- (float) cciMax{
    return cci_max;
}
- (float) cciLast{
    return cci_last;
}

#pragma mark ========== PSY ========== 
- (void) drawPSY:(CGContextRef)context{
    //NSLog(@" start drawVOL");
    // 获取当前的 k line 数据
    if ([kLineArray count] == 0) {
        return;
    }
    
    // 要绘制的条数
    int DRAW_COUNT = [AFSetting AF_DRAW_COUNT];
    
    if(nil == kLineArray || [kLineArray count] < DRAW_COUNT){
        return;
    }
    
    if (psy_array == nil) {
        // PSY
        [[AFPSY app] initKlineArray:kLineArray];
        
        // RSI DATA M6
        [[AFPSY app] psyData];
        
        psy_array = [[AFPSY app] kPSYArray];
        
        psy_min = [AFPSY kpiMinPSY];
        psy_max = [AFPSY kpiMaxPSY];
    }

    draw_psy_array = [psy_array subarrayWithRange:NSMakeRange(S_DRAW_INDEX, DRAW_COUNT)];
    
    //*
    psy_min = 100000;
    psy_max = 0;
    int psy_count = (int)[draw_psy_array count];
    float f_min_max = 0;
    for (int i = 0; i < psy_count; i++) {
        f_min_max = [[draw_psy_array objectAtIndex:i] floatValue];
        
        if (psy_max < f_min_max) {
            psy_max = f_min_max;
        }
        if (psy_min > f_min_max) {
            psy_min = f_min_max;
        }
    }
    //*/
    
    float x1,y1;
    
    // 绘制 K
    CGContextSetLineWidth(context, 1.0);
//    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0);
     CGContextSetRGBStrokeColor(context,101.0f/255.0f, 180.0f/255.0f, 255.0f/255.0f, 1.0); // 蓝色
    
    float volume_h = [AFSetting QUARTZ_KPI_H]/(psy_max - psy_min); // 实际高度／间隔高度 ＝ y轴分段高度
    float min_w = [AFSetting QUARTZ_KPI_W]/DRAW_COUNT;
    
    float psy = 0;
    int _count = (int)[draw_psy_array count];
    for (int i = 0; i< _count; i++) {
        psy = [[draw_psy_array objectAtIndex:i] floatValue];
        
        psy_last = psy;
        
        psy = psy - psy_min;
        
        x1 = s_x + i*min_w;
        y1 = [AFSetting QUARTZ_KPI_H] - psy*volume_h;
        
        if(isnan(y1)){
            return;
        }
        if (i == 0) {
            CGContextMoveToPoint(context, x1, y1);
        } else {
            CGContextAddLineToPoint(context, x1, y1);
        }
    }
    
    CGContextStrokePath(context);
}

- (float) psyMin{
    return psy_min;
}
- (float) psyMax{
    return psy_max;
}
- (float) psyLast{
    return psy_last;
}


#pragma mark ========== Notify ========== 
-(void) NotifKpiDateUpdate{
    if ([self.delegate respondsToSelector:@selector(kpiQuartzViewDrawEnd)]) {
        [self.delegate kpiQuartzViewDrawEnd];
    }
}

-(NSDictionary *) kpiCurrentPointInfo:(float)_x{
    
    kpiPointA = @"0";
    kpiPointB = @"0";
    kpiPointC = @"0";
    
    NSMutableDictionary *_dict = [NSMutableDictionary dictionary];
    
    int _count = [AFSetting AF_DRAW_COUNT];
    float _p = [AFSetting QUARTZ_KLINE_W]/_count;
    
    int _index = floor(_x/_p);
    
    if (_index >= _count) {
        return nil;
    }
    
    NSLog(@" _count = %i , _index = %i ", _count, _index);
    
    // 0: MACD平滑异同平均线
    // 1: VOL成交量
    // 2: RSI强弱指标
    // 3: BOLL布林线
    // 4: KDJ随机指标
    // 5: OBV能量潮
    // 6: CCI顺势
    // 7: PSY心里线
    if (kpiType == 0) {
        if ([draw_macdData count] > _index) {
            kpiPointA = [draw_macdData objectAtIndex:_index];
            kpiPointB = [draw_difData objectAtIndex:_index];
            kpiPointC = [draw_dmData objectAtIndex:_index];
        }
    }
    else if (kpiType == 1) {
        if ([draw_volBarData count] > _index) {
            kipDict = [draw_volBarData objectAtIndex:_index];
            kpiPointA = [kipDict objectForKey:AF_K_MARKET_VOLUME];

            kpiPointB = [draw_volLineDataM5 objectAtIndex:_index];
            kpiPointC = [draw_volLineDataM10 objectAtIndex:_index];
        }
    } else if (kpiType == 2) {
        if ([draw_rsiDataM6 count] > _index) {
            kpiPointA = [draw_rsiDataM6 objectAtIndex:_index];
            kpiPointB = [draw_rsiDataM12 objectAtIndex:_index];
        }
    }
    else if (kpiType == 3) {
        if ([draw_bool_averageArray count] > _index) {
            kpiPointA = [draw_bool_averageArray objectAtIndex:_index];
            kpiPointB = [draw_bool_upArray objectAtIndex:_index];
            kpiPointC = [draw_bool_downArray objectAtIndex:_index];
        }
    }
    else if (kpiType == 4) {
        if ([draw_kdj_k_dataArray count] > _index) {
            kpiPointA = [draw_kdj_k_dataArray objectAtIndex:_index];
            kpiPointB = [draw_kdj_d_dataArray objectAtIndex:_index];
            kpiPointC = [draw_kdj_j_dataArray objectAtIndex:_index];
        }
    }
    else if (kpiType == 5) {
        if ([draw_obv_array count] > _index) {
            kpiPointA = [draw_obv_array objectAtIndex:_index];
        }
    }
    else if (kpiType == 6) {
        if ([draw_cci_array count] > _index) {
            kpiPointA = [draw_cci_array objectAtIndex:_index];
        }
    }
    else if (kpiType == 7) {
        if ([draw_psy_array count] > _index) {
            kpiPointA = [draw_psy_array objectAtIndex:_index];
        }
    }

    [_dict setObject:kpiPointA forKey:@"kipPointA"];
    [_dict setObject:kpiPointB forKey:@"kipPointB"];
    [_dict setObject:kpiPointC forKey:@"kipPointC"];
    return _dict;
}
@end
